<?php
/**
 *+------------------
 * madong
 *+------------------
 * Copyright (c) https://gitee.com/motion-code  All rights reserved.
 *+------------------
 * Author: Mr. April (405784684@qq.com)
 *+------------------
 * Official Website: http://www.madong.tech
 */

namespace madong\webman\wf\services;

use madong\webman\wf\basic\BaseService;
use madong\ingenious\enums\ProcessConstEnum;
use madong\ingenious\ex\LFlowException;
use madong\ingenious\interface\model\IProcessForm;
use madong\ingenious\interface\model\IProcessFormHistory;
use madong\ingenious\interface\services\IProcessFormService;
use madong\ingenious\libs\utils\ArrayHelper;
use madong\ingenious\libs\utils\AssertHelper;
use madong\ingenious\libs\utils\Pagination;
use madong\ingenious\libs\utils\PropertyCopier;
use madong\webman\wf\dao\ProcessFormDao;

class ProcessFormService extends BaseService implements IProcessFormService
{

    public function __construct()
    {
        $this->dao = new ProcessFormDao();
    }

    public function created(object $param): ?IProcessForm
    {
        unset($param->id);
        $model = $this->dao->getModel();
        PropertyCopier::copyProperties($param, $model);
        return $this->dao->save($model->toArray());
    }

    public function del(string|array|int $data): array
    {
        return $this->transaction(function () use ($data): array {
            $data       = is_array($data) ? $data : explode(',', $data);
            $deletedIds = [];
            foreach ($data as $id) {
                $item = $this->dao->get($id, ['*'], ['history']);
                if (!$item) {
                    continue; // 如果找不到项，跳过
                }
                $item->history()->delete();//删除关联历史记录
                $item->delete();//删除主表
                $primaryKey   = $item->getPk();
                $deletedIds[] = $item->{$primaryKey};
            }
            return $deletedIds;
        });

    }

    public function updated(object $param): bool
    {
        AssertHelper::notNull($param->id ?? '', '参数ID不能为空');
        $model = $this->dao->get($param->id);
        PropertyCopier::copyProperties($param, $model);
        return $model->save();
    }

    public function list(object $param): array
    {
        $where = ArrayHelper::paramsFilter($param, [
            ['type_id', ''],
            ['name', ''],
            ['enabled', 1],
            ['pid', 0],
        ]);
        [$page, $limit] = Pagination::getPageValue($param);
        $items = $this->dao->selectList($where, '*', $page, $limit, 'name asc', ['types'], true);
        $total = $this->dao->count($where, true);
        return compact('items', 'total');
    }

    public function listByType(object $param): array
    {
        $where = ArrayHelper::paramsFilter($param, [
            ['name', ''],
            ['enabled', 1],
            ['pid', 0],
        ]);
        [$page, $limit] = Pagination::getPageValue($param);
        return $this->dao->selectList($where, '*', $page, $limit, 'sort desc', ['parent', 'items'], true)->toArray();
    }

    public function findById(string|int|array $id): ?IProcessForm
    {
        $record = $this->dao->get($id, ['*'], ['types', 'history']);
        if ($record && $record->history) {
            $latestHistory          = $record->history->sortByDesc('version')->first();
            $record->latest_history = $latestHistory; // 将最新的历史记录添加到模型中
        }
        return $record;
    }

    public function updateDesign(object $jsonObject): ?IProcessFormHistory
    {
        try {
            return $this->transaction(function () use ($jsonObject) {
                $data                  = new \stdClass();
                $data->process_form_id = $jsonObject->{ProcessConstEnum::PROCESS_FORM_ID_KEY->value};
                $data->create_user     = $jsonObject->{ProcessConstEnum::CREATE_USER->value};
                $processDesign         = $this->dao->get($data->process_form_id);
                if (empty($processDesign)) {
                    throw new LFlowException('单据主体不存在或被删除');
                }
                PropertyCopier::copyProperties($data, $processDesign);
                $processDesign->save();
                $data->content = $jsonObject->{ProcessConstEnum::PROCESS_FORM_KEY->value};
                //创建历史记录
                $processFormHistoryService = new ProcessFormHistoryService();
                return $processFormHistoryService->created($data);
            });
        } catch (\Exception $e) {
            throw new LFlowException($e->getMessage());
        }
    }
}
